﻿using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using WeatherHistory.Api.CommandsQueries.Commands.Weathers.Create;
using WeatherHistory.Api.CommandsQueries.Commands.Weathers.Delete;
using WeatherHistory.Api.CommandsQueries.Commands.Weathers.Update;
using WeatherHistory.Api.CommandsQueries.Queries.Weathers.GetLast;
using WeatherHistory.Api.CommandsQueries.Queries.Weathers.Search;
using WeatherHistory.Api.Filters;
using WeatherHistory.Shared.Validation;

namespace WeatherHistory.Api.Controllers;

/// <summary>
///     Контроллер для работы с погодой
/// </summary>
[ServiceFilter(typeof(AuthFilter))]
[Route("region/weather")]
public class WeatherController : ApiControllerBase
{
    /// <summary>Создание записи о погоде</summary>
    [HttpPost]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(CreateWeathersCommandResponse), StatusCodes.Status201Created)]
    public async Task<ActionResult<CreateWeathersCommandResponse>> Create([FromBody] CreateWeathersCommandRequest request)
    {
        var result = await Mediator.Send(request);
        return Ok(result);
    }

    /// <summary>Получение последней созданной записи о погоде в регионе</summary>
    [HttpGet("{regionId:long}")]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(GetLastWeathersQueryResponse), StatusCodes.Status200OK)]
    public async Task<ActionResult<GetLastWeathersQueryResponse>> GetLast([FromRoute] [GreaterThan(0L)] long regionId)
    {
        var request = new GetLastWeathersQueryRequest();
        request.RegionId = regionId;

        var result = await Mediator.Send(request);
        return Ok(result);
    }

    /// <summary>Удаление всех записей погоды в регионе</summary>
    [HttpDelete("{regionId:long}")]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public async Task<ActionResult> Delete([FromRoute] [GreaterThan(0L)] long regionId)
    {
        var request = new DeleteWeathersCommandRequest();
        request.RegionId = regionId;

        await Mediator.Send(request);
        return Ok();
    }

    /// <summary>Обновление последней созданной записи о погоде в регионе</summary>
    [HttpPut("{regionId:long}")]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(UpdateWeathersCommandResponse), StatusCodes.Status200OK)]
    public async Task<ActionResult<UpdateWeathersCommandResponse>> Update([FromBody] UpdateWeathersCommandRequest request, [FromRoute] [GreaterThan(0L)] long regionId)
    {
        request.OldRegionId = regionId;
        var result = await Mediator.Send(request);
        return Ok(result);
    }

    /// <summary>Получение актуальных записей о погоде*, которые попадают под фильтр и имеют прогноз погоды на ближайшие дни</summary>
    /// <remarks>Актуальная запись о пиогоде - последняя прикреплённая погода для региона</remarks>
    [HttpGet("search")]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status401Unauthorized)]
    [ProducesResponseType(typeof(SearchWeathersQueryResponse), StatusCodes.Status200OK)]
    public async Task<ActionResult<SearchWeathersQueryResponse>> Search([FromQuery] SearchWeathersQueryRequest request)
    {
        var result = await Mediator.Send(request);
        return Ok(result);
    }
}